#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>

// Function to get current time as string
void get_current_time(char *time_buf) {
    time_t now = time(NULL);
    struct tm *t = localtime(&now);
    strftime(time_buf, 20, "%Y-%m-%d %H:%M:%S", t);
}

// Function to format MAC address
void format_mac_address(const u_char *mac, char *mac_buf) {
    sprintf(mac_buf, "%02X-%02X-%02X-%02X-%02X-%02X", 
            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

// Packet handler function
void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
    struct ethhdr *eth_header = (struct ethhdr *)packet;
    
    // Check if it's an IP packet
    if (ntohs(eth_header->h_proto) == ETH_P_IP) {
        struct iphdr *ip_header = (struct iphdr *)(packet + sizeof(struct ethhdr));
        
        // Get current time
        char time_str[20];
        get_current_time(time_str);
        
        // Format MAC addresses
        char src_mac[18], dst_mac[18];
        format_mac_address(eth_header->h_source, src_mac);
        format_mac_address(eth_header->h_dest, dst_mac);
        
        // Format IP addresses
        char src_ip[16], dst_ip[16];
        sprintf(src_ip, "%d.%d.%d.%d", 
                (ip_header->saddr) & 0xFF,
                (ip_header->saddr >> 8) & 0xFF,
                (ip_header->saddr >> 16) & 0xFF,
                (ip_header->saddr >> 24) & 0xFF);
        sprintf(dst_ip, "%d.%d.%d.%d", 
                (ip_header->daddr) & 0xFF,
                (ip_header->daddr >> 8) & 0xFF,
                (ip_header->daddr >> 16) & 0xFF,
                (ip_header->daddr >> 24) & 0xFF);
        
        // Output CSV format to file
        FILE *log_file = fopen("network_traffic.csv", "a");
        if (log_file != NULL) {
            fprintf(log_file, "%s,%s,%s,%s,%s,%d\n", 
                    time_str, src_mac, src_ip, dst_mac, dst_ip, header->len);
            fclose(log_file);
        }
        
        // Also print to console
        printf("%s,%s,%s,%s,%s,%d\n", 
               time_str, src_mac, src_ip, dst_mac, dst_ip, header->len);
    }
}

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle;
    
    printf("Starting network packet sniffer...\n");
    printf("Output format: Time,Source MAC,Source IP,Destination MAC,Destination IP,Frame Length\n");
    
    // Open network interface for capture
    handle = pcap_open_live("ens33", BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Error opening device: %s\n", errbuf);
        return 1;
    }
    
    // Create CSV file with header
    FILE *log_file = fopen("network_traffic.csv", "w");
    if (log_file != NULL) {
        fprintf(log_file, "Time,Source MAC,Source IP,Destination MAC,Destination IP,Frame Length\n");
        fclose(log_file);
    }
    
    printf("Capture started. Press Ctrl+C to stop.\n");
    
    // Start packet capture loop
    pcap_loop(handle, 0, packet_handler, NULL);
    
    // Close the capture handle
    pcap_close(handle);
    
    return 0;
}
